#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象

const char *host = "192.168.0.123"; // 将要连接的服务器地址
const int httpPort = 80;            // 将要连接的服务器端口

void setup()
{
    Serial.begin(9600);
    Serial.println("");

    // 设置开发板LED引脚
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);

    wifiMulti.addAP("301fang", "lyq1988w112233");

    int i = 0;
    while (wifiMulti.run() != WL_CONNECTED)
    { // 尝试进行wifi连接。
        delay(1000);
        Serial.print(i++);
        Serial.print(' ');
    }

    // WiFi连接成功后将通过串口监视器输出连接成功信息
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(WiFi.SSID()); // WiFi名称
    Serial.print("IP address:\t");
    Serial.println(WiFi.localIP()); // IP
}

void loop()
{
    httpRequest("/");
    delay(2000);
    httpRequest("/info");
    delay(2000);
    httpRequest("/digital_pin");
    delay(2000);
}

// 向服务器请求信息并对信息进行解析
void httpRequest(String url)
{
    WiFiClient client;

    String httpRequest = String("GET ") + url + " HTTP/1.1\r\n" +
                         "Host: " + host + "\r\n" +
                         "Connection: close\r\n\r\n";

    Serial.print("Connecting to ");
    Serial.print(host);

    if (client.connect(host, 80))
    {
        Serial.println(" Success!");

        // 向服务器发送http请求信息
        client.print(httpRequest);
        Serial.println("Sending request: ");
        Serial.println(httpRequest);

        // 获取并显示服务器响应状态行
        String status_response = client.readStringUntil('\n');
        Serial.print("status_response: ");
        Serial.println(status_response);

        // 使用find跳过HTTP响应头
        if (client.find("\r\n\r\n"))
        {
            Serial.println("Found Header End. Start Parsing.");
        }

        parseInfo(client);
    }
    else
    {
        Serial.println(" connection failed!");
    }
    //断开客户端与服务器连接工作
    client.stop();
}

void parseInfo(WiFiClient client)
{
    String info_name_str;
    bool d3_bool;

    const size_t capacity = JSON_OBJECT_SIZE(1) + 3 * JSON_OBJECT_SIZE(3) + 140;
    DynamicJsonDocument doc(capacity);

    deserializeJson(doc, client);

    JsonObject info = doc["info"];
    if (info)
    {
        Serial.println("Server Json has info: true");
        const char *info_name = info["name"];   // "taichimaker"
        const char *info_url = info["url"];     // "www.taichi-maker.com"
        const char *info_email = info["email"]; // "taichimaker@163.com"
        info_name_str = info["name"].as<String>();
        Serial.print("info_name_str = ");
        Serial.println(info_name_str);
    }
    else
    {
        Serial.println("Server Json has info: false");
    }

    JsonObject digital_pin = doc["digital_pin"];
    if (digital_pin)
    {
        Serial.println("Server Json has digital_pin: true");
        const char *digital_pin_d1 = digital_pin["d1"]; // "1"
        const char *digital_pin_d2 = digital_pin["d2"]; // "0"
        const char *digital_pin_d3 = digital_pin["d3"]; // "1"
        d3_bool = digital_pin["d3"].as<int>();
        Serial.print("d3_bool = ");
        Serial.println(d3_bool);
    }
    else
    {
        Serial.println("Server Json has digital_pin: false");
    }

    const char *analog_pin_a0 = doc["analog_pin"]["a0"]; // "500"
    if (analog_pin_a0)
    {
        Serial.println("Server Json has analog_pin_a0: true");
    }
    else
    {
        Serial.println("Server Json has analog_pin_a0: false");
    }

    d3_bool == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH);
}